/*
 * Copyright (C) 2016 Bilibili
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bilibili.magicasakura.utils;

import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.solidxml.TypedAttribute;

import com.bilibili.magicasakura.widgets.Tintable;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by xyczero on 15/9/6.
 * Email : xyczero@sina.com
 */
public class ThemeUtils {
    public static final Color themeColor = Color.BLACK;
    private static final ThreadLocal<TypedAttribute> TL_TYPED_VALUE = new ThreadLocal<>();

    private static final int[] TEMP_ARRAY = new int[1];

    public static int getColorById(Context context, Color color) {
        return replaceColorById(context, color);
    }

    public static int getColor(Context context, int color) {
        return replaceColor(context, color);
    }

    public static AbilitySlice getWrapperActivity(Context context) {
        if (context instanceof AbilitySlice) {
            return (AbilitySlice) context;
        }
        return null;
    }

    public static void refreshUI(Context context, Component rootView) {
        refreshUI(context, null, rootView);
    }

    public static void refreshUI(Context context, ExtraRefreshable extraRefreshable, Component rootView) {
        TintManager.clearTintCache();
        refreshView(rootView, extraRefreshable);
    }

    private static Field sRecyclerBin;
    private static Method sListViewClearMethod;

    private static void refreshView(Component view, ExtraRefreshable extraRefreshable) {
        if (view == null) return;

        if (view instanceof Tintable) {
            ((Tintable) view).tint();
            if (view instanceof ComponentContainer) {
                for (int i = 0; i < ((ComponentContainer) view).getChildCount(); i++) {
                    refreshView(((ComponentContainer) view).getComponentAt(i), extraRefreshable);
                }
            }
        } else {
            if (extraRefreshable != null) {
                extraRefreshable.refreshSpecificView(view);
            }
            if (view instanceof ListContainer) {
                try {
                    if (sRecyclerBin == null) {
                        sRecyclerBin = ListContainer.class.getDeclaredField("mRecycler");
                        sRecyclerBin.setAccessible(true);
                    }
                    if (sListViewClearMethod == null) {
                        sListViewClearMethod = Class.forName("ohos.agp.components.ListContainer$RecycleBin")
                            .getDeclaredMethod("clear");
                        sListViewClearMethod.setAccessible(true);
                    }
                    sListViewClearMethod.invoke(sRecyclerBin.get(view));
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                BaseItemProvider adapter = ((ListContainer) view).getItemProvider();
                if (adapter instanceof BaseItemProvider) {
                    adapter.notifyDataInvalidated();
                }
            }
            if (view instanceof ComponentContainer) {
                for (int i = 0; i < ((ComponentContainer) view).getChildCount(); i++) {
                    refreshView(((ComponentContainer) view).getComponentAt(i), extraRefreshable);
                }
            }
        }
    }

    public interface ExtraRefreshable {
        void refreshGlobal(AbilitySlice abilitySlice);

        void refreshSpecificView(Component view);
    }

    private static switchColor mSwitchColor;

    public static void setSwitchColor(switchColor switchColor) {
        mSwitchColor = switchColor;
    }

    static int replaceColorById(Context context, Color color) {
        return mSwitchColor == null ? color.getValue() : mSwitchColor.replaceColorById(context, color);
    }

    static int replaceColor(Context context, int colorValue) {
        return mSwitchColor == null ? colorValue : mSwitchColor.replaceColor(context, colorValue);
    }

    public interface switchColor {

        int replaceColorById(Context context, Color color);

        int replaceColor(Context context, int colorValue);

    }
}
